package com.cwt_taxi_xa.protocol.can.meter;

import android.os.Handler;
import android.os.Message;

import com.cwt_taxi_xa.constants.ConstantsEvaluate;
import com.cwt_taxi_xa.constants.MyStatus;
import com.cwt_taxi_xa.protocol.MCUUtil;
import com.cwt_taxi_xa.service.FloatService;
import com.cwt_taxi_xa.util.AppLog;

import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by undi on 2019/7/22 17:26
 * 软件计价器
 *
 */
public abstract class SoftWareMeter {
    String TAG = "SoftWareMeter";

    private boolean debug = true;
    //半程计价
    private boolean halfWayBilling = false;

    SimpleDateFormat df = new SimpleDateFormat("HH:mm");

    WeakReference<IViewMeter> weakReference;

    private int startMileage = 0;
    //总里程
    private int totalMileage = 0;
    //总花费
    private double totalPrice = 0;
    //起步价
    private float startingPrice = 8.5f;
    //计时
    private String timing = "";

    private Thread mThread;
    //低俗补贴
    private boolean subsidySlow = false;

    public SoftWareMeter() {
    }
    //起步公里
    public abstract int startingKilometer();
    //补贴公里
    public abstract int subsidyKilometer();
    //运价
    public abstract float freightRate();

    public void register(IViewMeter viewMeter){
        weakReference  = new WeakReference<>(viewMeter);
        viewMeter.freightRate(freightRate());
        viewMeter.timing(timing);
        viewMeter.totalMileage(totalMileage);
        viewMeter.totalPrice(totalPrice);
        viewMeter.totalPeople(FloatService.peopleNumber);
    }

    public void unregister(IViewMeter viewMeter){
        if(weakReference != null){
            weakReference.clear();
        }
    }

    public void start(){
        totalPrice = startingPrice;
        if(isNightBilling()){
            totalPrice++;
        }
        startMileage = MCUUtil.mVehicleInformation.getTotalMileage();
        onVehicleSpeedChange(MCUUtil.mVehicleInformation.getVehicleSpeed());
        mStartAgingTime = System.nanoTime();
        agingTime();
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(weakReference != null){
                    IViewMeter iViewMeter = weakReference.get();
                    if(iViewMeter != null){
                        iViewMeter.totalPrice(SoftWareMeter.this.totalPrice);
                    }
                }
            }
        });
    }

    public void stop(){
        ConstantsEvaluate.clearEvaluateValue();
        mHandler.removeMessages(MSG_AGING_TIMER);
        totalMileage = 0;
        FloatService.peopleNumber =0;
        timing = "";
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(weakReference != null){
                    IViewMeter iViewMeter = weakReference.get();
                    if(iViewMeter != null){
                        iViewMeter.freightRate(freightRate());
                        iViewMeter.totalMileage(SoftWareMeter.this.totalMileage);
                        iViewMeter.timing(timing);
                        iViewMeter.totalPrice(SoftWareMeter.this.totalPrice);
                        iViewMeter.totalPeople(FloatService.peopleNumber);
                    }
                }
            }
        });
        AppLog.d(TAG,"totalPrice:" + totalPrice);
    }
    //总里程
    public int getTotalMileage() {
        return totalMileage;
    }

    public void setTotalPeople(final int value){
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(weakReference != null){
                    IViewMeter iViewMeter = weakReference.get();
                    if(iViewMeter != null){
                        iViewMeter.totalPeople(value);
                    }
                }
            }
        });
    }

    public boolean isHalfWayBilling() {
        return halfWayBilling;
    }

    public void setHalfWayBilling(boolean halfWayBilling) {
        this.halfWayBilling = halfWayBilling;
    }

    public void onTotalMileageChange(int totalMileage) {
        if(!MyStatus.zhongche){//空车不处理
            printLogE("onTotalMileageChange zhongche:" + MyStatus.zhongche);
            return;
        }
        //if((totalMileage - this.totalMileage - startMileage) == 1){//
        printLogD("onTotalMileageChange TotalMileage:" + totalMileage);
        if(!subsidySlow){//超时补贴
            addOneKilometer();
        }
        this.totalMileage = (totalMileage - startMileage);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(weakReference != null){
                    IViewMeter iViewMeter = weakReference.get();
                    if(iViewMeter != null){
                        iViewMeter.totalMileage(SoftWareMeter.this.totalMileage);
                    }
                }
            }
        });
    }

    public void onVehicleSpeedChange(double value){
        if(!MyStatus.zhongche){//空车不处理7
            printLogE("onTotalMileageChange zhongche:" + MyStatus.zhongche);
            return;
        }
        printLogD("onVehicleSpeedChange VehicleSpeed:" + value);
        if(((int)value) <= 10){
            startTimer();
        }else{
            stopTimer();
        }
    }

    //每增加1公里
    private void addOneKilometer(){
        //超出起步价
        if(totalMileage > startingKilometer()){
            //方案1(每公里运价加收0.3)
            planOne();
            //方案2
            //planTwo();
        }
    }

    private void planOne(){
        totalPrice += freightRate();
        printLogD("planOne" + AppLog.generateTag(3));
        if(isNightBilling()){
            totalPrice += 0.3;
        }
        //超出空驶补贴
        if(totalMileage> subsidyKilometer()){
            printLogD("planOne 超出空驶补贴:" + (freightRate()/2));
            totalPrice += (freightRate()/2);
        }
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(weakReference != null){
                    IViewMeter iViewMeter = weakReference.get();
                    if(iViewMeter != null){
                        iViewMeter.totalPrice(SoftWareMeter.this.totalPrice);
                    }
                }
            }
        });
    }

    private void planOneHalf(){
        totalPrice += freightRate()/2;
        printLogD("planOneHalf" + AppLog.generateTag(3));
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(weakReference != null){
                    IViewMeter iViewMeter = weakReference.get();
                    if(iViewMeter != null){
                        iViewMeter.totalPrice(SoftWareMeter.this.totalPrice);
                    }
                }
            }
        });
    }

    private void planOtherHalf(){
        totalPrice += freightRate()/2;
        printLogD("planOneHalf" + AppLog.generateTag(3));
        if(isNightBilling()){
            totalPrice += 0.3;
        }
        //超出空驶补贴
        if(totalMileage> subsidyKilometer()){
            printLogD("planOne 超出空驶补贴:" + (freightRate()/2));
            totalPrice += (freightRate()/2);
        }
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(weakReference != null){
                    IViewMeter iViewMeter = weakReference.get();
                    if(iViewMeter != null){
                        iViewMeter.totalPrice(SoftWareMeter.this.totalPrice);
                    }
                }
            }
        });
    }


    private void planTwo(){
        totalPrice += freightRate() + 0.3;
        //超出空驶补贴
        if(totalMileage> subsidyKilometer()){
            totalPrice += ((freightRate() + 0.3)/2);
        }
    }

    /**
     * 夜间计费
     * @return
     */
    private boolean isNightBilling(){
        return !belongTime("06:00","23:00");
    }

    /**
     * 高峰拥堵按时计价
     * @return
     */
    private boolean isPeakHours(){
        return belongTime("07:00","09:00")|| belongTime("17:00","19:00");
    }

    private long sleepTime(){
        if(isPeakHours()){
            return 4*60*1000;
        }else{
            return 5*60*1000;//startTimer time:300000
        }
    }
    private synchronized void startTimer(){
        printLogD("startTimer ");
        subsidySlow = true;
        if(mThread == null){
            mThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (!Thread.currentThread().isInterrupted()){
                        try {

                            long time = sleepTime();
                            printLogD("startTimer time:" + time);
                            Thread.sleep(time/2);
                            if(halfWayBilling){
                                planOneHalf();
                            }
                            Thread.sleep(time/2);
                            if(halfWayBilling){
                                planOtherHalf();
                            }else{
                                //一公里运价
                                planOne();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            printLogE("startTimer e.getMessage:" + e.getMessage());
                            break;
                        }
                    }
                }
            });
            mThread.start();
        }
    }

    private synchronized void stopTimer(){
        subsidySlow = false;
        if(mThread != null){
            mThread.interrupt();
            mThread = null;
        }
    }

    private boolean belongTime(String begin,String end){
        boolean result = false;
        try {
            Date now = df.parse(df.format(new Date()));
            Date beginTime = df.parse(begin);
            Date endTime = df.parse(end);
            result = belongCalendar(now, beginTime, endTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 判断时间是否在时间段内
     *
     * @param nowTime
     * @param beginTime
     * @param endTime
     * @return
     */
    public static boolean belongCalendar(Date nowTime, Date beginTime,
                                         Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }
    //BrightFormula    白天
    //NightFormula     晚上

    private static final int MSG_AGING_TIMER = 1001;
    private static final long AGING_TIME = 1 * 1000L;
    //目标老化时间为毫秒数
    private long mTargetAgingTime = 0;
    //当前老化时间
    private long mCurrAgingTime = 0;
    private long mStartAgingTime = 0;
    private Handler mHandler = new AgingTimerHandler();

    private class AgingTimerHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_AGING_TIMER:

                    agingTime();
                    break;
                default:
                    break;
            }
        }
    }

    private void agingTime() {
        //printLogD("agingTime");
        //这里获取到的是纳秒数,转成毫秒数
        mCurrAgingTime = (System.nanoTime() - mStartAgingTime) / 1000L / 1000L;
        timing = updateCurrentTime(mCurrAgingTime);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if(weakReference != null){
                    IViewMeter iViewMeter = weakReference.get();
                    if(iViewMeter != null){
                        iViewMeter.timing(timing);
                    }
                }

            }
        });
        mHandler.removeMessages(MSG_AGING_TIMER);
        mHandler.sendEmptyMessageDelayed(MSG_AGING_TIMER, AGING_TIME);
    }

    /**
     * 小时数无限显示
     *
     * @param time 毫秒数
     * @return String
     */
    private String updateCurrentTime(long time) {
        final long spaceTime = time / 1000;
        final long spaceSecond = spaceTime % 60;
        long spaceMinute = spaceTime / 60;
        final long spaceHour = spaceMinute / 60;
        final long thespaceMinute = spaceMinute % 60;
        final String timeStr = String.format("%02d:%02d:%02d", spaceHour, thespaceMinute, spaceSecond);
        return timeStr;
    }

    void printLogD(String msg){
        if(debug){
            AppLog.d(TAG,msg);
        }
    }

    void printLogE(String msg){
        if(debug){
            AppLog.e(TAG,msg);
        }
    }
}
